package threads;
/**
 * Java的主要四大接口
 * Clonable,用于对象克隆
 * Comparable，用于对象比较
 * Serializable，用于对象序列化
 * Runnable,用于对象线程化*/
public class Biji {
    /**
     * 执行多线程时继承Thread类的线程直接new Thread().start()就可以；
     *    实现Runnable接口的线程要封装在Thread中才可以执行，new Thread(new Runnable2()).start()
     * 实现多线程时，线程必须继承(extends)Thread类，实现run方法（java.lang.Thread）
     * 或者是实现（implements）Runnable接口里的run方法，此接口可以让类具有线程化
     *多线程写在run方法里，启动的时候调用start方法，会自动以新进程调用run方法
     * 直接调用润方法，将变成串行执行，即类似于单核执行
     * 同一个线程，只能start一次，多次执行会报错；多个线程同时启动，线程间的顺序是随机的，操作系统说了算
     *线程无需关闭，run方法执行完就自动关闭了
     * main函数可能早于新线程结束，整个程序并不终止；而整个程序终止是等所有线程都结束才终止
     * 在做多线程时，只有调用start方法才会是线程执行，直接运行run方法是单线执行
     *一般使用Runnable实现多线程
     * 启动run程序时，要先new Thread().start()
     * 无论是Thread还是Runnable都要封装在Thread下才可以启动，然后再通过start方法来启动
     * */
    /**线程之间一个数据被读取的步骤：
     * 首先读取主存里面的值，然后把值放到自己的工作缓存（副本）中去
     * 每个cpu执行副本的数据操作
     * cpu将执行的结果写到副本缓存中去
     * 然后再将工作缓存的副本刷到主存中去*/

    /**粗粒度：子线程和子线程之间，和main线程之间没有信息交流
     * 细粒度：线程之间有信息的交流
     * 一般通过共享变量达到信息共享，因为点对点的信息Java还不支持，但可以调用c++的MPI库
     * 通过static进行全局信息数据共享*/
    /**线程间进行数据共享时，为了保证数据的准确性，一次只能有一个线程去修改共享线程
     *多线程之间进行信息交流贡献时遇到的问题：
     * 1、工作缓存副本被修改：
     * 多线程进行信息共享时，每个线程都有自己的工作缓存副本，当线程需要数据的时候是从内存里加载数据到工作缓存里，然后才开始运算
     * 然而每个线程都有自己的工作缓存，当其他的数据要使用数据时都从自己的工作缓存里加载数据，但共享数据被其他数据修改他们不知道
     * 也就是，每个线程用的工作缓存副本都是其那一刻的值，但后面被修改了导致数据不准确
     * 2、关键步骤缺乏枷锁限制（共享数据时的步骤）：
     * 当对同一个变量进行枷锁限制时需要进行枷锁限制，即关键变量在使用时一次只能有一个线程去修改它，其他线程不能同时进行修改
     *
     * 对于一个数据共享被修改时，可使用关键字volatile修饰关键数据，这样在数据被修改时其他线程也能够看到
     * 保证不同线程对共享变量的操作可见性
     * volatile是解决线程中工作副本可见性问题
     *
     * 互斥：某一个线程运行一个代码段(关键区)，其他线程不能同时运行这个代码段
     * 同步：多个线程的运行，必须按照某一种规定的先后顺序来运行
     * 互斥是同步的一个特例
     * 互斥的关键字是synchronized---只能一个线程进入，但增加了性能负担
     * synchronized枷锁只能枷锁到一个对象上，即对象是一把锁
     *
     * 和synchronized类似的互斥锁还有Lock,比它更高级，更细粒度
     * Lock锁可以实现同步的效果，实现更复杂的临界区域结构，其中的方法tryLock()可以与判断锁是否空闲
     * Lock锁可以允许读写分离的操作，可同时进行多个读，一个写
     * 主要的类有：ReentrantLock类，可重入的互斥锁
     * ReentrantReadWriteLock类，可重入的读写锁
     * 其中重要的两个方法为：锁住资源的锁lock(),释放资源的锁unlock()
     * */

    /**线程的生命周期：
     * 用jvisualvm管理工具可以查看线程状态
     * -new状态，刚创建的时候
     * -start状态，就绪的时候
     * -run状态，运行中
     * -sleep状态，阻塞状态
     * -terminated状态，结束
     * 线程管理（线程阻塞与被唤醒）:
     * sleep方法，时间一到，线程自己会醒来
     * wait/notify/notifyAll,处于等待，需要其他线程来唤醒
     * join方法，等待另外一个线程结束
     * interrupt方法，向另外一个线程发送中断信号，该线程收到信号后，会出发InterruptedException(可解除阻塞)，进行下一步处理
     *interrupted()方法时Thread类的方法，用来检测当前线程是否收到一个中断信号，平时状态是false，收到才是true==!interrupted()
     *一般用线程主动监控共享变量来主动退出或者共享问题
     *
     * 线程主动暂停和终止：
     * 定期检测共享变量，获取共享变量要按顺序获取，不能互相占用
     * 暂停或终止时，先释放资源，再主动动作
     * 暂停：Thread.sleep(),即休眠
     * 终止：run方法结束，线程终止
     * */
    /**
     * 线程预防死锁，可以对资源进行等级排序
     * 可以创建守护线程：守护线程的结束是根据run方法的结束或者main函数的结束而结束的
     * 定义守护线程：在run方法或者main函数中对象调用setDaemon(true);就设置了守护线程
     * 守护进程即是后台进程
     * 守护线程永远不要访问资源，如文件和数据库等
     * 在编程时让线程进行变量控制，自动监控变量
     * */

    /**
     * 并行编程的模式：
     * --主从模式（主线程指挥从线程去执行）
     * Worker模式（所有的线程都是平等的，无中心化的，即p2p模式）
     *
     * 并发编程：
     * --继承Thread/实现Runnable/Thread组管理
     * --Executor框架
     * --Fork-Join框架*/
    /**线程组ThreadGroup
     * 线程组只是提供一个数组的方式来方式来方便线程的管理
     * 可以用enumerate方法遍历组内活跃的线程，并把线程拷贝到数组中
     * 线程组的效率低，线程无法重用
     * activeCount()方法返回线程组中还处于活跃的线程数
     * interrupt()方法对所有的线程发出interrupt中断信号
     * list()方法打印线程中所欲的线程信息*/
    /**
     * Executor并发框架
     *包含在java.util.concurrent.*包中
     * 框架作用：1、分离任务的创建和执行者的创建
     *          2、线程重复利用问题（因为new一个线程的代价是很大的）
     *共享线程池的概念：
     * 1、预设好多个Thread，可以弹性增加或者减少
     * 2、Thread可以多次执行很小很多的任务，执行完之后就自动释放
     * 3、任务创建和执行过程是分开的，不需要关联
     * 4、程序员无需关心线程池执行任务的过程
     * Executor框架主要类：
     * ExecutorService线程池服务类：它代表整个线程池；它是靠Executors类中的newCachedThreadPool方法
     *                                      和newFixedThreadPool(固定线程)
     *Callable类：跟Runnable类差不多，它的方法call()类似于run()方法，但有返回值
     * Future类：该类包含着线程执行完以后存储的结果放在里面*/
    /**Executor并行编程方法：
     * 定义一个共享线程池ThreadPoolExecutor tpe=(ThreadPoolExecutor)Executors.newCachedThreadPool()
     *          或者ThreadPoolExecutor tpe=(ThreadPoolExecutor)Executors.newFixedThreadPool(5)
     *利用list泛型来存放Future返回的结果：List<Future<Integer>> resultList=new ArrayList<>()
     * 向线程池提交任务： tpe.execute(任务)/Future<Integer> result=tpe.submit(任务的返回对象)。
     *      （此处的任务的返回的对象是实现implements Callable类中的call方法，有返回值）
     * 把任务添加进Future里：resultList.add(result)
     * 查询Future中的所有线程，然后判断是否已经完成idDone()
     *              Future<Integer> res=resultList.get(i),i是resultList.size()遍历大小
     *              ult=resultList.get(i);
     *              System.out.println("任务："+i+result.isDone());
     * 关闭线程池：tpe.shutdown()
     * 注意：任务中要实现或继承线程类Runnable/Thread/Callable
     * Executor框架中实现线程的Callable类里的call()方法*/
/**
 *Fork-Join框架：（适用于二分法）
 * 适用于整体任务量不好确定的场合（最小任务可确定）
 * 即先把大人物拆成小任务，计算了小任务，再加起来计算大任务
 *Fork-Join主要类：
 * ForkJoinPool类：任务池类，类似于ThreadPoolExecutor
 * RecursiveAction类：
 * RecursiveTask类：需要实现compute方法
 * 类似于递归程序*/

/**多线程并发数据结构：
 * 常用的数据结构是线程不安全的
 * 对于多线程的数据结构，ArrayList/HashMap/HashSet是非同步的，多个线程同时读写会抛出异常
 * 并发数据结构分为(数据添加和删除)：
 * ——阻塞式集合：当集合为空或者满的时候，等待
 * ——非阻塞式集合：当集合为空或者满时，不等待，返回null或者异常
 * List有序列表类数据结构：
 *——Vector同步安全，写多读少，但性能较差
 * ——ArrayList不安全
 * ——Collections.synchronizedList(List list) 基于synchronized，安全但效率差
 * CopyOnWriteArrayList，基于复制机制的，非阻塞，适合读多写少---适用于有序的多线程读
 *Set无序列表数据结构：
 * ——HashSet在数据结构中是不安全的
 * ——Collections.synchronizedSet(Set set)基于synchronized，安全但效率差
 * ——CopyOnWriteArraySet，是基于复制机制实现的，适合读多写少，非阻塞---适用无序的多线程数据读
 *Map映射数据结构：
 * ——Hashtable同步安全，写多读少，但性能较差
 * ——HashMap不安全
 * ——Collections.synchronizedMap(Map map),基于synchronized，但效率差
 * ——ConcurrentHashMap读多写少，非阻塞----适合读k-v对
 * Queue&Deque队列的数据结构：
 * ——ConcurrentLinkedQueue 非阻塞
 * ——ArrayBlockingQueue/LinkedBlockingQueue 阻塞*/
/**
 * 信号量：Semaphore
 * 定义：类似于一个计数器，可以设置多个并发量
 * 其方法有--acquire()获取信号量，把原来的信号量减一
 *       ---release()释放信号量，把原来的信号量加一
 *比Lock更进一步，可以同时访问多个关键区*/
/**
 * Latch等待锁，它是一个辅助类锁
 * 用来协调多线程任务的执行的，表示用来保护临界区域或者共享资源的
 * 主要类有CountDownLatch
 * ---方法countDownLatch()计数减一
 * ---方法await()等待latch变成0
 * */
/**
 * Barrier锁，也是同步辅助类
 * 允许多个线程在某一个点上进行同步
 * 主要类为CyclicBarrier
 * ---构造函数是需要同步的线程数量
 * await等待其他线程，到达数量后就自动放行*
 * 适合用于递归归并计算*/
/**Phaser，也是辅助类
 * 允许执行并发多阶段任务
 * 在每一个阶段结束的位置对线程进行同步，当所有的线程都到达这步，再进行下一步
 * 主要类为Phaser
 * ----arrive()方法
 * ----arriveAndwaitAdvance()方法
 * */
/**Exchanger用于在线程间互相发送消息，以前线程之间要有信息交流必须有共享变量volatile
 * 消息交流原理：两个线程中定义一个同步点，当两个线程都达到同步点时，它们交换数据结构
 * 主要类为Exchanger,其中的方法为exchange(),线程双方交互数据，交互数据是双向的*/
/**利用TimeTask制作简单的定时器，让线程按照固定时间执行
 * TimerTask封装任务
 * Timer类 定时器*/
     }
